﻿using System.Collections.Generic;
using UnityEngine;

namespace AI.Graph {


    [RequireComponent (typeof (MeshFilter))]
    public class FieldOfViewMesh : MonoBehaviour {

        public float meshResolution = 1;
        public float maskCutawayDistance = .1f;

        private MeshFilter viewMeshFilter;
        private Mesh viewMesh;


        void Awake () {
            viewMeshFilter = GetComponent<MeshFilter> ();

            viewMesh = new Mesh ();
            viewMesh.name = "Field Of View Mesh";

            viewMeshFilter.mesh = viewMesh;
        }


        public void GenerateFieldOfViewMesh (float viewAngle, float viewRadius, LayerMask obstacleMask) {
            int numSteps = Mathf.RoundToInt (viewAngle * meshResolution);
            float anglePerStep = viewAngle / numSteps;

            List<Vector3> viewMeshPoints = new List<Vector3> ();

            for (int i = 0; i <= numSteps; i++) {
                float angle = transform.eulerAngles.y - viewAngle / 2F + anglePerStep * i;
                Vector3 direction = new Vector3 (Mathf.Sin (angle * Mathf.Deg2Rad), 0, Mathf.Cos (angle * Mathf.Deg2Rad));

                if (Physics.Raycast (transform.position, direction, out RaycastHit hit, viewRadius, obstacleMask)) {
                    viewMeshPoints.Add (hit.point);
                }
                else {
                    viewMeshPoints.Add (transform.position + direction * viewRadius);
                }
            }

            int vertexCount = viewMeshPoints.Count + 1;
            Vector3[] vertices = new Vector3[vertexCount];
            int[] triangles = new int[(vertexCount - 2) * 3];

            vertices[0] = Vector3.zero;
            for (int i = 0; i < vertexCount - 1; i++) {
                vertices[i + 1] = transform.InverseTransformPoint (viewMeshPoints[i]) + Vector3.forward * maskCutawayDistance;

                if (i < vertexCount - 2) {
                    triangles[i * 3] = 0;
                    triangles[i * 3 + 1] = i + 1;
                    triangles[i * 3 + 2] = i + 2;
                }
            }

            viewMesh.Clear ();
            viewMesh.vertices = vertices;
            viewMesh.triangles = triangles;
            viewMesh.RecalculateNormals ();
        }

    }


}